package org.dromara.setting.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lxk.service.setting.api.SettingServiceApi;
import com.lxk.service.setting.response.ChannelAllDto;
import com.lxk.service.setting.response.ChannelWXPayDto;
import com.lxk.service.setting.response.ChannelYueDto;
import com.lxk.service.setting.response.SettingConfigItemDto;
import lombok.AllArgsConstructor;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.setting.domain.SettingConfigItem;
import org.dromara.setting.domain.vo.SettingConfigGroupVo;
import org.dromara.setting.domain.vo.SettingConfigItemVo;
import org.dromara.setting.enums.SettingAllEnums;
import org.dromara.setting.mapper.SettingConfigItemMapper;
import org.dromara.setting.service.ISettingConfigGroupService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class SettingServiceApiImpl implements SettingServiceApi {

    private final ISettingConfigGroupService settingConfigGroupService;
    private final SettingConfigItemMapper baseMapper;

    @Override
    public ChannelYueDto yueDetail() {

        ChannelYueDto vo = new ChannelYueDto();
        SettingConfigGroupVo queryByType = settingConfigGroupService.queryByType(SettingAllEnums.BalancePayEnums.YUE);
        if (ObjectUtil.isNull(queryByType)) {
            return vo;
        }
        LambdaQueryWrapper<SettingConfigItem> lqw = Wrappers.lambdaQuery();
        lqw.eq(SettingConfigItem::getConfigGroupId, queryByType.getId());
        List<SettingConfigItemVo> itemList = baseMapper.selectVoList(lqw);
        if (CollUtil.isEmpty(itemList)) {
            return vo;
        }
        List<SettingConfigItemDto> list = MapstructUtils.convert(itemList, SettingConfigItemDto.class);
        Map<String, SettingConfigItemDto> map = list.stream().collect(Collectors.toMap(SettingConfigItemDto::getKey, v -> v));
        vo.setName(map.get(SettingAllEnums.BalancePayEnums.NAME.getKey()));
        vo.setIcon(map.get(SettingAllEnums.BalancePayEnums.ICON.getKey()));
        vo.setSort(map.get(SettingAllEnums.BalancePayEnums.SORT.getKey()));
        SettingConfigItemDto state = map.get(SettingAllEnums.BalancePayEnums.STATE.getKey());
        vo.setState(state);
        return vo;
    }

    /**
     * 微信支付配置组
     */
    @Override
    public ChannelWXPayDto wxPayDetail() {
        ChannelWXPayDto vo = new ChannelWXPayDto();
        SettingConfigGroupVo queryByType = settingConfigGroupService.queryByType(SettingAllEnums.WxPayEnums.WX_PAY);
        if (ObjectUtil.isNull(queryByType)) {
            return vo;
        }
        LambdaQueryWrapper<SettingConfigItem> lqw = Wrappers.lambdaQuery();
        lqw.eq(SettingConfigItem::getConfigGroupId, queryByType.getId());
        List<SettingConfigItemVo> itemList = baseMapper.selectVoList(lqw);
        if (CollUtil.isEmpty(itemList)) {
            return vo;
        }
        List<SettingConfigItemDto> list = MapstructUtils.convert(itemList, SettingConfigItemDto.class);
        Map<String, SettingConfigItemDto> map = list.stream().collect(Collectors.toMap(SettingConfigItemDto::getKey, v -> v));
        vo.setSlAppId(map.get(SettingAllEnums.WxPayEnums.SLAPPID.getKey()));
        vo.setSlMchId(map.get(SettingAllEnums.WxPayEnums.SLMCHID.getKey()));
        vo.setAppId(map.get(SettingAllEnums.WxPayEnums.APPID.getKey()).getValue());
        vo.setCertPath(map.get(SettingAllEnums.WxPayEnums.CERT_PATH.getKey()));
        vo.setCertP12Path(map.get(SettingAllEnums.WxPayEnums.CERT_P12_PATH.getKey()));
        vo.setKeyPath(map.get(SettingAllEnums.WxPayEnums.KEY_PATH.getKey()));
        vo.setPartnerKey(map.get(SettingAllEnums.WxPayEnums.PARTNER_KEY.getKey()));
        vo.setApiKey(map.get(SettingAllEnums.WxPayEnums.API_KEY.getKey()));
        vo.setApiKey3(map.get(SettingAllEnums.WxPayEnums.API_KEY3.getKey()));
        vo.setMchId(map.get(SettingAllEnums.WxPayEnums.MCH_ID.getKey()));
        vo.setDomain(map.get(SettingAllEnums.WxPayEnums.DOMAIN.getKey()));
        vo.setWxPayNotifyUrl(map.get(SettingAllEnums.WxPayEnums.WX_PAY_NOTIFY_URL.getKey()));
        vo.setWxRefundNotifyUrl(map.get(SettingAllEnums.WxPayEnums.WX_REFUND_NOTIFY_URL.getKey()));
        vo.setTenantId(queryByType.getTenantId());
        return vo;
    }


    @Override
    public List<ChannelWXPayDto> wxPayConfigByTenantId(String tenantId) {
        TenantHelper.setDynamic(tenantId);
        List<SettingConfigGroupVo> queryByType = settingConfigGroupService.queryListByType(SettingAllEnums.WxPayEnums.WX_PAY);
        if (CollUtil.isEmpty(queryByType)) {
            return new ArrayList<>();
        }
        List<Long> groupIdList = queryByType.stream().map(SettingConfigGroupVo::getId).collect(Collectors.toList());
        LambdaQueryWrapper<SettingConfigItem> lqw = Wrappers.lambdaQuery();
        lqw.in(SettingConfigItem::getConfigGroupId, groupIdList);
        List<SettingConfigItemVo> itemList = baseMapper.selectVoList(lqw);
        if (CollUtil.isEmpty(itemList)) {
            return new ArrayList<>();
        }
        List<SettingConfigItemDto> dtoItemList = MapstructUtils.convert(itemList, SettingConfigItemDto.class);
        Map<Long, List<SettingConfigItemDto>> groupIdAndItemDtoMap = dtoItemList.stream().collect(Collectors.groupingBy(SettingConfigItemDto::getConfigGroupId));
        List<ChannelWXPayDto> voList = new ArrayList<>();
        for (SettingConfigGroupVo group : queryByType) {
            List<SettingConfigItemDto> list = groupIdAndItemDtoMap.get(group.getId());
            Map<String, SettingConfigItemDto> map = list.stream().collect(Collectors.toMap(SettingConfigItemDto::getKey, v -> v));
            ChannelWXPayDto vo = new ChannelWXPayDto();
            vo.setTenantId(tenantId);
            vo.setSlAppId(map.get(SettingAllEnums.WxPayEnums.SLAPPID.getKey()));
            vo.setSlMchId(map.get(SettingAllEnums.WxPayEnums.SLMCHID.getKey()));
            vo.setAppId(map.get(SettingAllEnums.WxPayEnums.APPID.getKey()).getValue());
            vo.setCertPath(map.get(SettingAllEnums.WxPayEnums.CERT_PATH.getKey()));
            vo.setCertP12Path(map.get(SettingAllEnums.WxPayEnums.CERT_P12_PATH.getKey()));
            vo.setKeyPath(map.get(SettingAllEnums.WxPayEnums.KEY_PATH.getKey()));
            vo.setPartnerKey(map.get(SettingAllEnums.WxPayEnums.PARTNER_KEY.getKey()));
            vo.setApiKey(map.get(SettingAllEnums.WxPayEnums.API_KEY.getKey()));
            vo.setApiKey3(map.get(SettingAllEnums.WxPayEnums.API_KEY3.getKey()));
            vo.setMchId(map.get(SettingAllEnums.WxPayEnums.MCH_ID.getKey()));
            vo.setDomain(map.get(SettingAllEnums.WxPayEnums.DOMAIN.getKey()));
            vo.setWxPayNotifyUrl(map.get(SettingAllEnums.WxPayEnums.WX_PAY_NOTIFY_URL.getKey()));
            vo.setWxRefundNotifyUrl(map.get(SettingAllEnums.WxPayEnums.WX_REFUND_NOTIFY_URL.getKey()));
            voList.add(vo);
        }
        TenantHelper.clearDynamic();
        return voList;
    }

    /**
     * 微信支付配置组
     */
    @Override
    public List<ChannelWXPayDto> wxPayAllList() {
        List<SettingConfigGroupVo> queryByType = settingConfigGroupService.queryListByType(SettingAllEnums.WxPayEnums.WX_PAY);
        if (CollUtil.isEmpty(queryByType)) {
            return new ArrayList<>();
        }
        List<Long> groupIdList = queryByType.stream().map(SettingConfigGroupVo::getId).collect(Collectors.toList());
        LambdaQueryWrapper<SettingConfigItem> lqw = Wrappers.lambdaQuery();
        lqw.in(SettingConfigItem::getConfigGroupId, groupIdList);
        List<SettingConfigItemVo> itemList = baseMapper.selectVoList(lqw);
        if (CollUtil.isEmpty(itemList)) {
            return new ArrayList<>();
        }
        List<SettingConfigItemDto> dtoItemList = MapstructUtils.convert(itemList, SettingConfigItemDto.class);
        Map<Long, List<SettingConfigItemDto>> groupIdAndItemDtoMap = dtoItemList.stream().collect(Collectors.groupingBy(SettingConfigItemDto::getConfigGroupId));
        List<ChannelWXPayDto> voList = new ArrayList<>();
        for (SettingConfigGroupVo group : queryByType) {
            String tenantId = group.getTenantId();
            List<SettingConfigItemDto> list = groupIdAndItemDtoMap.get(group.getId());
            Map<String, SettingConfigItemDto> map = list.stream().collect(Collectors.toMap(SettingConfigItemDto::getKey, v -> v));
            ChannelWXPayDto vo = new ChannelWXPayDto();
            vo.setTenantId(tenantId);
            vo.setSlAppId(map.get(SettingAllEnums.WxPayEnums.SLAPPID.getKey()));
            vo.setSlMchId(map.get(SettingAllEnums.WxPayEnums.SLMCHID.getKey()));
            vo.setAppId(map.get(SettingAllEnums.WxPayEnums.APPID.getKey()).getValue());
            vo.setCertPath(map.get(SettingAllEnums.WxPayEnums.CERT_PATH.getKey()));
            vo.setCertP12Path(map.get(SettingAllEnums.WxPayEnums.CERT_P12_PATH.getKey()));
            vo.setKeyPath(map.get(SettingAllEnums.WxPayEnums.KEY_PATH.getKey()));
            vo.setPartnerKey(map.get(SettingAllEnums.WxPayEnums.PARTNER_KEY.getKey()));
            vo.setApiKey(map.get(SettingAllEnums.WxPayEnums.API_KEY.getKey()));
            vo.setApiKey3(map.get(SettingAllEnums.WxPayEnums.API_KEY3.getKey()));
            vo.setMchId(map.get(SettingAllEnums.WxPayEnums.MCH_ID.getKey()));
            vo.setDomain(map.get(SettingAllEnums.WxPayEnums.DOMAIN.getKey()));
            vo.setWxPayNotifyUrl(map.get(SettingAllEnums.WxPayEnums.WX_PAY_NOTIFY_URL.getKey()));
            vo.setWxRefundNotifyUrl(map.get(SettingAllEnums.WxPayEnums.WX_REFUND_NOTIFY_URL.getKey()));
            voList.add(vo);
        }
        return voList;
    }

    /**
     * 支付宝支付配置组
     */
    @Override
    public ChannelAllDto allDetail() {
        ChannelAllDto vo = new ChannelAllDto();
        SettingConfigGroupVo queryByType = settingConfigGroupService.queryByType(SettingAllEnums.AliPayEnums.ALL_PAY);
        if (ObjectUtil.isNull(queryByType)) {
            return vo;
        }
        LambdaQueryWrapper<SettingConfigItem> lqw = Wrappers.lambdaQuery();
        lqw.eq(SettingConfigItem::getConfigGroupId, queryByType.getId());
        List<SettingConfigItemVo> itemList = baseMapper.selectVoList(lqw);
        if (CollUtil.isEmpty(itemList)) {
            return vo;
        }
        List<SettingConfigItemDto> list = MapstructUtils.convert(itemList, SettingConfigItemDto.class);
        Map<String, SettingConfigItemDto> map = list.stream().collect(Collectors.toMap(SettingConfigItemDto::getKey, v -> v));
        vo.setAliAppId(map.get(SettingAllEnums.AliPayEnums.ALI_APP_ID.getKey()).getValue());
        vo.setAliPrivateKey(map.get(SettingAllEnums.AliPayEnums.ALI_PRIVATE_KEY.getKey()));
        vo.setAliPayPublicKey(map.get(SettingAllEnums.AliPayEnums.ALI_PAY_PUBLIC_KEY.getKey()));
        vo.setAliAppCertPath(map.get(SettingAllEnums.AliPayEnums.ALI_APP_CERT_PATH.getKey()));
        vo.setAliPayCertPath(map.get(SettingAllEnums.AliPayEnums.ALI_PAY_CERT_PATH.getKey()));
        vo.setServerUrl(map.get(SettingAllEnums.AliPayEnums.SERVER_URL.getKey()));
        vo.setAliPayRootCertPath(map.get(SettingAllEnums.AliPayEnums.ALI_PAY_ROOT_CERT_PATH.getKey()));
        vo.setAliNotifyUrl(map.get(SettingAllEnums.AliPayEnums.ALI_NOTIFY_URL.getKey()));
        vo.setAliRefundUrl(map.get(SettingAllEnums.AliPayEnums.ALI_REFUND_URL.getKey()));
        return vo;
    }

    /**
     * 微信支付配置列表
     *
     * @return
     */
    @Override
    public List<ChannelAllDto> aliPayList() {
        List<SettingConfigGroupVo> queryByType = settingConfigGroupService.queryListByType(SettingAllEnums.AliPayEnums.ALL_PAY);
        if (CollUtil.isEmpty(queryByType)) {
            return new ArrayList<>();
        }
        List<Long> groupIdList = queryByType.stream().map(SettingConfigGroupVo::getId).collect(Collectors.toList());
        LambdaQueryWrapper<SettingConfigItem> lqw = Wrappers.lambdaQuery();
        lqw.in(SettingConfigItem::getConfigGroupId, groupIdList);
        List<SettingConfigItemVo> itemList = baseMapper.selectVoList(lqw);
        if (CollUtil.isEmpty(itemList)) {
            return new ArrayList<>();
        }
        List<SettingConfigItemDto> dtoItemList = MapstructUtils.convert(itemList, SettingConfigItemDto.class);
        Map<Long, List<SettingConfigItemDto>> groupIdAndItemDtoMap = dtoItemList.stream().collect(Collectors.groupingBy(SettingConfigItemDto::getConfigGroupId));
        List<ChannelAllDto> voList = new ArrayList<>();
        for (SettingConfigGroupVo group : queryByType) {
            List<SettingConfigItemDto> list = groupIdAndItemDtoMap.get(group.getId());
            Map<String, SettingConfigItemDto> map = list.stream().collect(Collectors.toMap(SettingConfigItemDto::getKey, v -> v));
            ChannelAllDto vo = new ChannelAllDto();
            vo.setAliAppId(map.get(SettingAllEnums.AliPayEnums.ALI_APP_ID.getKey()).getValue());
            vo.setTenantId(group.getTenantId());
            SettingConfigItemDto payMode = map.get(SettingAllEnums.AliPayEnums.PAY_MODE.getKey());
            if (payMode != null && StrUtil.isNotBlank(payMode.getValue())) {
                vo.setPayMode(payMode.getValue());
            }
            vo.setAliPrivateKey(map.get(SettingAllEnums.AliPayEnums.ALI_PRIVATE_KEY.getKey()));
            vo.setAliPayPublicKey(map.get(SettingAllEnums.AliPayEnums.ALI_PAY_PUBLIC_KEY.getKey()));
            vo.setAliAppCertPath(map.get(SettingAllEnums.AliPayEnums.ALI_APP_CERT_PATH.getKey()));
            vo.setAliPayCertPath(map.get(SettingAllEnums.AliPayEnums.ALI_PAY_CERT_PATH.getKey()));
            vo.setServerUrl(map.get(SettingAllEnums.AliPayEnums.SERVER_URL.getKey()));
            vo.setAliPayRootCertPath(map.get(SettingAllEnums.AliPayEnums.ALI_PAY_ROOT_CERT_PATH.getKey()));
            vo.setAliNotifyUrl(map.get(SettingAllEnums.AliPayEnums.ALI_NOTIFY_URL.getKey()));
            vo.setAliRefundUrl(map.get(SettingAllEnums.AliPayEnums.ALI_REFUND_URL.getKey()));
            voList.add(vo);
        }
        return voList;
    }
}
